package com.gzcstec.product.service.impl;

import com.gzcstec.product.dataobject.DecreaseStockInput;
import com.gzcstec.product.dataobject.ProductInfo;
import com.gzcstec.product.dataobject.ProductInfoOutput;
import com.gzcstec.product.enums.ExceptionCodeEnums;
import com.gzcstec.product.enums.ProductStatusEnums;
import com.gzcstec.product.exception.ProductException;
import com.gzcstec.product.repository.ProductInfoRepository;
import com.gzcstec.product.service.ProductService;
import com.gzcstec.product.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductInfoRepository productInfoRepository;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public List<ProductInfo> findUpAll() {
        return productInfoRepository.findByProductStatus(ProductStatusEnums.UP.getCode());
    }

    @Override
    public List<ProductInfoOutput> list(List<String> productList) {
       return productInfoRepository.findByProductIdIn(productList)
               .stream().map(e -> {
                   ProductInfoOutput productInfoOutput = new ProductInfoOutput();
                   BeanUtils.copyProperties(e , productInfoOutput);
                   return productInfoOutput;
               })
               .collect(Collectors.toList());
    }

    @Override
    public void decreaseStock(List<DecreaseStockInput> cartDTOList) {
        //调用商品扣库存服务
        List<ProductInfo> productInfoList = decreaseStockP(cartDTOList);
        //发送商品库存信息到消息队列
        //productInfo => productInfoOutput
        List<ProductInfoOutput> productInfoOutputList = productInfoList.stream().map(e -> {
            ProductInfoOutput productInfoOutput = new ProductInfoOutput();
            BeanUtils.copyProperties(e , productInfoOutput);
            return productInfoOutput;
        }).collect(Collectors.toList());
        amqpTemplate.convertAndSend("productInfo" , JsonUtils.toJson(productInfoOutputList));
    }

    @Transactional
    public List<ProductInfo> decreaseStockP(List<DecreaseStockInput> cartDTOList) {
        List<ProductInfo> productInfoList = new ArrayList<>();
        for(DecreaseStockInput cartDTO : cartDTOList) {
            //查找商品是否存在
            Optional<ProductInfo> optional = productInfoRepository.findById(cartDTO.getProductId());
            if(!optional.isPresent()) {
                //商品不存在
                log.error("【减库存】商品不存在，cartDTO={}" , cartDTO);
                throw new ProductException(ExceptionCodeEnums.PRODUCT_NOT_EXIST);
            }

            ProductInfo productInfo = optional.get();
            Integer leftStock = productInfo.getProductStock() - cartDTO.getProductQuantity();
            if(leftStock < 0) {
                //商品库存不足
                log.error("【减库存】商品库存不足够，cartDTO={}" , cartDTO);
                throw new ProductException(ExceptionCodeEnums.PRODUCT_STOCK_ERROR);
            }

            //更新库存
            productInfo.setProductStock(leftStock);
            productInfoRepository.save(productInfo);
            productInfoList.add(productInfo);
        }

        return productInfoList;
    }

}
